/* [file: WDI/Source/Processor/parser.y] */
/*
 * WDI: Web Development Interface
 *
 * Copyright (c) 2009 - 2010, ODIS, Rizo Isrofov <irm@odisproject.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of the ODIS nor the names of its contributors may be
 *     used to endorse or promote products derived from this software without
 *     specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY ODIS ''AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL ODIS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

%{
	#include <stdio.h>
	#include <stdlib.h>
	
	#define DEFAULT_OUTFILE "wdi.out"

	/**
	 * \fn       void yyerror(const char* msg)
	 * \brief    Bison parser error routine
	 * \param    msg Message to be printed on error
	 */
	void yyerror(const char* msg);

	/**
	 * \fn        extern int yylex(void)
	 * \brief     External lexer function generated by Flex
	 * \return    Unique token identifier of matched text;
	 *            returns 0 on End-Of-Input
	 */
	extern int yylex(void);

	/**
	 * \var      *yyin, *yyout
	 * \brief    Input and output streams for lexer
	 */
	extern FILE *yyin, *yyout;

	/**
	 * \var      *progname
	 * \brief    Program name
	 */
	char *progname;
	
	/**
	 * \var      unsigned int line_cnt
	 * \brief    Line counter for input source code
	 */
	unsigned int line_cnt;

	/**
	 * \var    WDI-Processor usage information
	 */
	char* usage;

%}

%union {
	int  integer;    /* Integer values used in statements. */
	char *string;    /* Tags, identifiers and strings. */
}

%token <integer> INTEGER
%token <string>  TYPE IDENTIFIER STRING_LITERAL STRING_BLOCK FOR IN INCLUDE

%%

input
	: /* Empty input. */
	| input input_qualifier
	;

input_qualifier
	: expression  /* Returns printable content (no side effects). */
	/* | statement   / Executable code only (operation, instruction). */
	/* | definition  / Declaration and assignment of an identifier. */
	;

expression
	: ';'
	| primary_expression_list
	;

primary_expression_list
	: primary_expression
	| primary_expression_list ',' primary_expression
	;

primary_expression
	: number
	| block
	| string
	;

string
	: '?'
/* 	| STRING_BLOCK */
	;

number
	: INTEGER
	/* | REAL_NUMBER */
	;

block
	: '{' input '}'
	;








/*	: ';'
	| expression_list
	;

expression_list
	: primary_expression
	| expression_list ',' primary_expression
	;

primary_expression
	: string
	| variable_specifier
	| block
	;

string
	: STRING_LITERAL
	| STRING_BLOCK
	;

variable_specifier
	: IDENTIFIER
	| IDENTIFIER '(' attributes ')'
	;

block
	: '{' expression '}'
	| TYPE block
	;

attributes
	: /* Empty attributes. *
	| attribute_list
	;

attribute_list
	: attribute
	| attribute_list ',' attribute

attribute
	: key '=' value
	;

key
	: IDENTIFIER
	;

value
	: string
	| INTEGER
	/* | C: call for a function or a variable.  *
	;

statement
	: for_statement
	;

for_statement
	: FOR '(' for_condition ')' expression /* ? *
	;

for_condition
	: IDENTIFIER IN IDENTIFIER
	;

definition
	: declaration
	| assignment
	;

declaration
	: TYPE IDENTIFIER ';'
	;

assignment
	: TYPE IDENTIFIER  '=' expression
	;*/

/*primary_value
	: IDENTIFIER
	| INTEGER
	| STRING_LITERAL
	| STRING_BLOCK
	;*/
%%

void yyerror(msg)
	const char* msg;
{
	fprintf(stderr,">> %s\n", msg);
}

int main(argc, argv)
	int argc; char **argv;
{
	line_cnt = 0;
	usage = "%s: usage <infile> <outfile>\n";

	char *infile, *outfile;

	progname = argv[0];

	if (argc > 3) {
		fprintf(stderr, usage, progname);
		exit(1);
	}
	if (argc > 1) {
		infile = argv[1];
		yyin = fopen(infile, "r");
		if (yyin == NULL) {
			fprintf(stderr, "%s: cannot open %s\n", progname, infile);
			exit(1);
		}
	}

	if (argc > 2)
		outfile = argv[2];
	else
		outfile = DEFAULT_OUTFILE;

	yyout = fopen(outfile, "w");
	if (yyout == NULL) {
		fprintf(stderr, "%s: cannot open %s\n", progname, outfile);
		exit(1);
	}

	printf("%c[1;31m-- Web Development Interface%c[0m\n\n",27, 27);
	
	yyparse();
	printf(">> %d lines processed. Exiting...\n", line_cnt);
	return 0;
}

